﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using FrameworkLib.Facades.Paging;

namespace ControlsLib.Pagers
{
    [DefaultEvent("ItemClicked"), DefaultProperty("Items"), Designer("System.Windows.Forms.Design.ToolStripDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
    public class Pager1 : BindingNavigator, IPager
    {
        const int WM_KEYDOWN = 0x100;
        const int WM_KEYUP = 0x101;
        const int WM_CHAR = 0x102;
        const int WM_SYSCHAR = 0x106;
        const int WM_SYSKEYDOWN = 0x104;
        const int WM_SYSKEYUP = 0x105;
        const int WM_IME_CHAR = 0x286;

        public event EventHandler<NavigationEventArgs> PageChanged;

        private bool m_keyEnterPressed = false;
        private int m_numberOfPages = 0;
        private int[] m_elements = null;
        private int m_numberOfRecords = 0;

        public int NumberOfRecords
        {
            get { return m_numberOfRecords; }
            set 
            { 
                m_numberOfRecords = value;

                this.PositionItem.ToolTipText = string.Format("Records: {0}", m_numberOfRecords);
            }
        }

        public int NumberOfPages
        {
            get { return m_numberOfPages; }
            set 
            {
                if (m_numberOfPages != value)
                {
                    m_numberOfPages = value;
                    ResetSettings();
                }
                else
                {
                    m_numberOfPages = value;
                }

                //ResetSettings();
            }
        }

        public Pager1() : base(true)
        {
            
        }

        public void InitializeControl()
        {
            base.GripStyle = ToolStripGripStyle.Hidden;
            base.Items.Remove(base.DeleteItem);
            base.Items.Remove(base.AddNewItem);
            base.Dock = DockStyle.None;

            this.MoveFirstItem.Click += new EventHandler(MoveFirstItem_Click);
            this.MovePreviousItem.Click += new EventHandler(MovePreviousItem_Click);
            this.MoveNextItem.Click += new EventHandler(MoveNextItem_Click);
            this.MoveLastItem.Click += new EventHandler(MoveLastItem_Click);
            //this.PositionItem.TextChanged += new EventHandler(PositionItem_TextChanged);

            this.MoveFirstItem.AutoToolTip = false;
            this.MoveFirstItem.ToolTipText = string.Empty;
            this.MovePreviousItem.AutoToolTip = false;
            this.MovePreviousItem.ToolTipText = string.Empty;
            this.MoveNextItem.AutoToolTip = false;
            this.MoveNextItem.ToolTipText = string.Empty;
            this.MoveLastItem.AutoToolTip = false;
            this.MoveLastItem.ToolTipText = string.Empty;

            ResetSettings();
        }

        public void ResetSettings()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(ResetSettings));
            }
            else
            {
                if (m_elements == null)
                {
                    m_elements = new int[NumberOfPages];
                }
                else
                {
                    Array.Clear(m_elements, 0, m_elements.Length);
                    Array.Resize(ref m_elements, NumberOfPages);
                }

                for (int i = 0; i < NumberOfPages - 1; i++) m_elements.SetValue(i, i);

                this.BindingSource = new BindingSource(m_elements, "");
            }
        }

        protected override bool ProcessKeyPreview(ref Message m)
        {
            if ((m.Msg == WM_KEYDOWN) || (m.Msg == WM_SYSKEYDOWN))
            {
                KeyEventArgs e = new KeyEventArgs(((Keys)((int)((long)m.WParam))) | ModifierKeys);
                TrappedKeyDown(e);
            }

            return base.ProcessKeyPreview(ref m);
        }

        private void TrappedKeyDown(KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                m_keyEnterPressed = true;

                PositionItem_TextChanged(this, EventArgs.Empty);

                e.Handled = true;
                e.SuppressKeyPress = true;
            }
        }

        protected virtual void OnPageChanged(NavigationEventArgs e)
        {
            EventHandler<NavigationEventArgs> invoker = PageChanged;

            if (invoker != null) invoker(this, e);
        }

        void PositionItem_TextChanged(object sender, EventArgs e)
        {
            if (m_keyEnterPressed)
            {
                string value = this.PositionItem.Text;

                if (value != string.Empty)
                {
                    int position = 1;

                    if (int.TryParse(value, out position))
                    {
                        if (position == 0) position = 1;

                        m_keyEnterPressed = false;
                        OnPageChanged(new NavigationEventArgs(NavigationEventType.GotToPosition, position));
                    }
                }
            }
        }

        void MoveFirstItem_Click(object sender, EventArgs e)
        {
            OnPageChanged(new NavigationEventArgs(NavigationEventType.First));
        }

        void MovePreviousItem_Click(object sender, EventArgs e)
        {
            if (this.BindingSource.Position >= 0)
            {
                OnPageChanged(new NavigationEventArgs(NavigationEventType.Previous));
            }
        }

        void MoveNextItem_Click(object sender, EventArgs e)
        {
            if (this.BindingSource.Position < NumberOfPages)
            {
                OnPageChanged(new NavigationEventArgs(NavigationEventType.Next));
            }
        }

        void MoveLastItem_Click(object sender, EventArgs e)
        {
            OnPageChanged(new NavigationEventArgs(NavigationEventType.Last));
        }

        private void InitializeComponent()
        {
            ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
            this.SuspendLayout();
            // 
            // Pager1
            // 
            this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Pager1_KeyDown);
            ((System.ComponentModel.ISupportInitialize)(this)).EndInit();
            this.ResumeLayout(false);

        }

        private void Pager1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {

                m_keyEnterPressed = true;
            }
        }
    }
}
